package jwtx

import (
	"errors"
	"github.com/golang-jwt/jwt/v4"
)

type LoginClaims struct {
	ID          uint64 `json:"id"`
	RoleId 		uint64 `json:"role_id"`
	Username    string `json:"username"`
	BufferTime  int64  `json:"buffer_time"`
	jwt.RegisteredClaims
}

var (
	TokenExpired     = errors.New("Token is expired")
	TokenNotValidYet = errors.New("Token not active yet")
	TokenMalformed   = errors.New("That's not even a token")
	TokenInvalid     = errors.New("Couldn't handle this token:")
)

func GetAdminUserID(secretKey string, tokenString string) int64 {
	claims, err := SysParseToken(secretKey, tokenString)
	if err != nil {
		return 0
	}
	return int64(claims.ID)
}

// 解析 token
func SysParseToken(secretKey string, tokenString string) (*LoginClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &LoginClaims{}, func(token *jwt.Token) (i interface{}, e error) {
		return []byte(secretKey), nil
	})
	if err != nil {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, TokenMalformed
			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
				// Token is expired
				return nil, TokenExpired
			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				return nil, TokenNotValidYet
			} else {
				return nil, TokenInvalid
			}
		}
	}
	if token != nil {
		if claims, ok := token.Claims.(*LoginClaims); ok && token.Valid {
			return claims, nil
		}
		return nil, TokenInvalid
	} else {
		return nil, TokenInvalid
	}
}
